#ifndef _FV_LOG_H_
#define _FV_LOG_H_

#ifdef PARALLEL
#include"pch_intf.h"
#endif
#include<cstdio>
#include<fstream>

#ifdef FV_DEBUG
#define logd(msg, ...)	IO::log(IO::LOGCONSOLE, "DEBUG %s:%d: " msg "\n",__FILE__, __LINE__, ##__VA_ARGS__)
#define logd2(msg)  IO::log msg
#else
#define logd(msg)
#define logd2(msg)
#endif


namespace FemViewer {
namespace IO		{   
	
	
	enum { LOGCONSOLE = 0x001, LOGFILE = 0x010, LOGDIALOG = 0x100};
	class mfvWindow;

	class Log {
		static Log* _selfp;
		static bool _init;
	public:
		static bool Init(int mode=LOGCONSOLE,FILE* fp=stdout,mfvWindow* dlgp=NULL);
		static bool IsInit(void) { return _init; }
		static void Close();
		static Log& GetInstance();
		~Log();
		void msg(const char* str);
		void SetMode(const unsigned mode);
	private:
		Log(int mode=LOGCONSOLE, FILE* fp=NULL, mfvWindow* dlgp=NULL);
		void StartLogToFile();
		void EndLogToFile();
		int			  _mode;
		FILE*		  _logfilep;
		mfvWindow*    _logdlgp;
		std::ofstream _slogstrm;
		bool      	  _closelogfile;

#ifdef PARALLEL
		int 	  _myprocid;
		int 	  _mymasterid;
		int (*logto)(const char* str);
		static int sendlog(const char* str);
		static int updatelog(const char* str);
#endif
	};


	void log(const char *msg, ...);

	inline void log(int mode,const char *msg,...) {
		Log::GetInstance().SetMode(mode);
		log(msg);
	}

	inline void log2(const char *msg, ...) {
		Log::GetInstance().SetMode(LOGCONSOLE);
		log(msg);
	}

#ifdef PARALLEL
	void printParallel(const char*, ...);
	void printSynchronizedParallel(const char*, ...);
#endif


}// end namespace IO
}// end namespace FeemViewer



#endif
